package com.github.zdg.recyclerview;

import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.github.zdongcoding.recyclerview.R;

/**
 * Created by zoudong on 2017/6/5.
 */

public class LoadMoreHelper extends RecyclerView.Adapter {
    RecyclerView.Adapter mAdapter;
    public static final int LOAD_MORE = Integer.MIN_VALUE;
    private LoadMoreViewHolder mLoadMoreVieHolder;
    public static final int LOADMORE_ERROR = -1;
    public static final int LOADMORE_FINISH = 0;
    public static final int LOADMORE_LOADING = 1;
    public static final int LOADMORE_INIT = 2;
    private final RecyclerView.OnScrollListener mLoadMore = new RecyclerView.OnScrollListener() {

        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        }

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            perfromLoadMore(recyclerView, newState);
        }
    };

    public LoadMoreHelper(RecyclerView.Adapter adapter) {
        mAdapter = adapter;
        if (mAdapter == null) {
            throw new RuntimeException("adapter = null");
        }
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        recyclerView.addOnScrollListener(mLoadMore);
        mAdapter.registerAdapterDataObserver(mObserver);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridLayoutManager = (GridLayoutManager) manager;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int spanCount = gridLayoutManager.getSpanCount();
                    int viewType = getItemViewType(position);
                    return viewType != LOAD_MORE ? 1 : spanCount;
                }
            });
        }
        mAdapter.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        if (holder.getItemViewType() != LOAD_MORE) {
            mAdapter.onViewAttachedToWindow(holder);
        }

    }

    @Override
    public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {
        super.onViewDetachedFromWindow(holder);
        if (holder.getItemViewType() != LOAD_MORE) {
            mAdapter.onViewDetachedFromWindow(holder);
        }

    }

    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        mAdapter.unregisterAdapterDataObserver(mObserver);
        mAdapter.onDetachedFromRecyclerView(recyclerView);
        recyclerView.removeOnScrollListener(mLoadMore);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        if (viewType == LOAD_MORE) {
            return mLoadMoreVieHolder = (mLoadMoreVieHolder == null ? new LoadMoreViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_loadmore_layout, viewGroup, false)) : mLoadMoreVieHolder);
        }
        return mAdapter.onCreateViewHolder(viewGroup, viewType);
    }

    public void setLoadMoreViewHolder(LoadMoreViewHolder viewHolder) {
        this.mLoadMoreVieHolder = viewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        try {
            if (getItemViewType(position) != LOAD_MORE) {
                mAdapter.onBindViewHolder(viewHolder, position);
            }
        } catch (Throwable e) {
            e.printStackTrace();

        }


    }

    @Override
    public int getItemViewType(int position) {
        if (position == getItemCount() - 1) {
            return LOAD_MORE;
        }
        return mAdapter.getItemViewType(position);
    }

    @Override
    public int getItemCount() {
        if (mAdapter.getItemCount() > 0) {
            return mAdapter.getItemCount() + 1;
        }
        return mAdapter.getItemCount();
    }

    LoadMorelistener mLoadMorelistener;


    protected void perfromLoadMore(RecyclerView recyclerView, int newState) {
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        int visibleItemCount = layoutManager.getChildCount();
//        Log.e("zoudong", "visibleItemCount=" + visibleItemCount);
//        Log.e("zoudong", "itemCount=" + layoutManager.getItemCount());
        boolean triggerCondition = visibleItemCount > 0
//                    && newState == RecyclerView.SCROLL_STATE_IDLE
                && mLoadMoreVieHolder != null && mLoadMoreVieHolder.getStatus() == LOADMORE_INIT
                && canTriggerLoadMore(recyclerView);
        if (triggerCondition) {
            onLoadMore(recyclerView);
        }
    }

    protected boolean canTriggerLoadMore(RecyclerView recyclerView) {
        View lastChild = recyclerView.getChildAt(recyclerView.getChildCount() - 1);
        int position = recyclerView.getChildLayoutPosition(lastChild);
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        int totalItemCount = layoutManager.getItemCount();
//        Log.e("zoudong", "---totalItemCount=" + totalItemCount + "---" + position);

        return totalItemCount - 1 == position;
    }


    public void setLoadMorelistener(LoadMorelistener loadMorelistener) {
        mLoadMorelistener = loadMorelistener;
    }

    public void onLoadMore(RecyclerView recyclerView) {
        setLoadMoreStatus(LOADMORE_LOADING);
        if (mLoadMorelistener != null) {
            mLoadMorelistener.onLoadMore(recyclerView);
        }
    }

    public void setLoadMoreStatus(int status) {
        if (mLoadMoreVieHolder != null) {
            mLoadMoreVieHolder.setLoadMoreStatus(status);
        }
    }

    public interface LoadMorelistener {
        void onLoadMore(RecyclerView recyclerView);
    }

    public static class LoadMoreViewHolder extends RecyclerView.ViewHolder {
        private ProgressBar mProgressBar;
        private TextView tv_loading;
        private int mStatus;

        public LoadMoreViewHolder(View itemView) {
            super(itemView);
            mProgressBar = (ProgressBar) itemView.findViewById(R.id.pro_bar_loading);
            tv_loading = (TextView) itemView.findViewById(R.id.tv_loading);
            setLoadMoreStatus(LOADMORE_INIT);
        }

        public int getStatus() {
            return mStatus;
        }

        public void setLoadMoreStatus(int status) {
            mStatus = status;
            switch (status) {
                case LOADMORE_ERROR:
                    mProgressBar.setVisibility(View.GONE);
                    tv_loading.setVisibility(View.VISIBLE);
                    tv_loading.setText("出错了");
                    break;
                case LOADMORE_LOADING:
                    mProgressBar.setVisibility(View.VISIBLE);
                    tv_loading.setVisibility(View.VISIBLE);
                    tv_loading.setText("正在加载中...");
                    break;
                case LOADMORE_FINISH:
                    mProgressBar.setVisibility(View.GONE);
                    tv_loading.setVisibility(View.VISIBLE);
                    tv_loading.setText("已经是底线了");
                    break;
                case LOADMORE_INIT:
                    mProgressBar.setVisibility(View.GONE);
                    tv_loading.setVisibility(View.GONE);
                    break;
            }
        }
    }

    private RecyclerView.AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            LoadMoreHelper.this.notifyDataSetChanged();
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            LoadMoreHelper.this.notifyItemRangeChanged(positionStart, itemCount);
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
            LoadMoreHelper.this.notifyItemRangeChanged(positionStart, itemCount, payload);
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            LoadMoreHelper.this.notifyItemRangeInserted(positionStart, itemCount);
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            LoadMoreHelper.this.notifyItemRangeRemoved(positionStart, itemCount);
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            LoadMoreHelper.this.notifyDataSetChanged();
        }
    };
}
